﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DelegateLambda
{
    /*
     c#的匿名方法、Lambda表达式
    委托的扩展用途:匿名方法、Lambda表达式、和泛型结合、多线程使用...

    一、匿名方法和lambda表达式
    1.匿名方法：一个方法没有具体的名称，而只有关键字delegate、方法参数、方法体
    
    2.匿名方法好处: 将具体方法和委托直接关联在一起，如果委托只需要一个方法的时候，匿名方法肯定
    是显得简单

    3、Lambda表达式： 在c#3.0. 使用这种表达式可以更简练的编写代码块

        【1】在Lambda表达式中，参数类型可以是明确类型，也可以是推断类型.
        【2】如果是推断类型，在编辑器根据上下文自动推断
        【3】运算符=>读作goes to,运算符左边输入参数(如果有),右边是表达式或语句块
        【4】表达式两种表达方式
        (input args) => 表达式
        (input args) => {语句1;语句2;语句3...}
        【5】Lamdba表达式和匿名方法比较
         第一、Lambda表达式本身就是匿名方法
         第二、Lambda表达式允许不指明参数类型，但是匿名方法必须明确类型
         第三、Lambda表达式允许单一表达式或多条语句组成而这个匿名方法不允许单一表达式。

    二、自定义泛型委托
    1、为什么要使用泛型委托
    普通委托在数据类型的限定上非常严格，有时候我们的需求是变化的，可能就适应不了
    2、泛型委托定义:本质上和泛型方法非常相似，泛型委托关联的时候，可以是具体方法、匿名方法，
    也可以是Lambda表达式。

    三、系统泛型委托
    .Net平台早就考虑了如何区简化用户定义泛型委托的情况，也就是说.Net平台定义好，我们可以直接使用.

    两种方式:一种是没有返回值的Action<args>,一种是有返回值Fun<args>
    1、Action<args>在多线程中用的非常多。
    2、Fun<args>在扩展方法中用的非常多。其他地方也用。

    改造前面的系统泛型委托
    经验:大家以后凡是用到泛型委托，首先想到两个系统泛型委托

     */
    class Program
    {
        static void Main(string[] args)
        {
            /*LambdaDemo demo = new LambdaDemo();
            demo.Test1();*/

            GenericDelegate genericDelegate = new GenericDelegate();
            genericDelegate.Test();

            Console.ReadLine();
        } 
    }
}
